﻿using System;
using System.Collections.Generic;
using System.Data.Services;
using System.Data.Services.Common;
using System.Linq;
using System.ServiceModel.Web;
using System.Web;
using DataModel;
using System.Linq.Expressions;
using System.Web.Security;
namespace SocialPhotos
{
    public class PhotoCloud : DataService<DataModel.SocialPhotoModelContainer>
    {
        public static void InitializeService(DataServiceConfiguration config)
        {
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;         
        }

    //    public PhotoCloud()
    //{
    //    this.ProcessingPipeline.ProcessingRequest += new EventHandler<DataServiceProcessingPipelineEventArgs>(OnRequest);
    //}
    //    void OnRequest(object sender,
    //           DataServiceProcessingPipelineEventArgs e)
    //    {
    //        if (!CustomAuthenticationProvider.Authenticate(HttpContext.Current))
    //            throw new DataServiceException(401, "401 Unauthorized");
    //    }
    

        #region Custom Webmethod
        [WebGet]
        public void like(int id)
        {
            try
            {
                SocialPhotoModelContainer context = this.CurrentDataSource;
                Photo photo = context.Photos.Single(p => p.Id == id);
                if (photo != null)
                {
                    photo.Likes++;
                    context.SaveChanges();
                }
            }
            catch (Exception)
            {
            }
           // return "OK";
        }

        [WebGet]
        public void dislike(int id)
        {
            try
            {
                SocialPhotoModelContainer context = this.CurrentDataSource;
                Photo photo = context.Photos.Single(p => p.Id == id);
                if (photo != null)
                {
                    photo.Dislikes++;
                    context.SaveChanges();
                }
            }
            catch (Exception)
            {
            }
        }

        [WebGet]
        public IQueryable<Photo> getTodayPhotos()
        {
            SocialPhotoModelContainer context = this.CurrentDataSource;
            return context.Photos.Take(32);
        }

        [WebGet]
        public IQueryable<Photo> getTopRated(int number)
        {
            try
            {
                var photo = (from d in this.CurrentDataSource.Photos
                             orderby d.Likes descending
                             select d).Take(number);
                return photo;
            }
            catch
            {
                return null;
            }
        }

        [WebGet]
        public IQueryable<Photo> getRandomPhotos(int number)
        {
            //var qry = from photo in this.CurrentDataSource.Photos
            //          where photo.PublicLevel == 0
            //          orderby Guid.NewGuid()
            //          select photo;
            var qry = from photo in this.CurrentDataSource.Photos
                      orderby Guid.NewGuid()
                      select photo;
            return qry.Take(number);
        }

        [WebGet]
        public IQueryable<Photo> getPhotosByCategoryId(int id)
        {
            try
            {
                var photo = from d in this.CurrentDataSource.Photos
                            where d.Category.FirstOrDefault().Id == id
                            select d;
                return photo;
            }
            catch
            {
                return null;
            }
        }

        [WebGet]
        public IQueryable<Photo> getPhotosByUserId(int id)
        {
            //var photo = from p in this.CurrentDataSource.Photos
            //            join u in this.CurrentDataSource.Users on p.User.Id equals u.Id
            //            where
            //              u.Name == name
            //            select p;


            var photo = from d in this.CurrentDataSource.Photos
                        where d.User.Id == id
                        select d;
            return photo;
        }

        [WebGet]
        public IQueryable<Photo> getTopLike()
        {
            int top = 100;
            SocialPhotoModelContainer context = this.CurrentDataSource;
            var photo = (from p in context.Photos
                         where p.Likes >= 0
                         orderby p.Likes descending
                         select p).Take(top);
            return photo;
        }

        //[WebInvoke(Method = "POST")]
        [WebGet]
        public void postComment(int userID, int photoId, string comment)
        {
            SocialPhotoModelContainer context = this.CurrentDataSource;
            Photo photo = context.Photos.Single(p => p.Id == photoId);
            User user = context.Users.Single(p => p.Id == userID);

            Comment pComment = new Comment { User = user, Photo = photo, Content = comment, PostedTime = System.DateTime.Now };
            context.AddToComments(pComment);
            context.SaveChanges();
        }

        [WebGet]
        public IQueryable<User> signUp()
        {
            SocialPhotoModelContainer context = this.CurrentDataSource;
            string name = HttpContext.Current.Request.Headers["User"];
            string password = HttpContext.Current.Request.Headers["Pass"];
            var user = from u in context.Users
                       where u.Name == name
                       select u;
            int count = user.Count();
            if (count == 0) {
                User newUser = new User { Name = name, Password = password };
                context.AddToUsers(newUser);
                context.SaveChanges();
                
                return null;
            }else
            // Neu ton tai thi tra ve User - Client so sanh
            return user;
        }
 
        [WebGet]
        public IQueryable<Comment> getCommentsOfAPhoto(int photoId)
        {
            SocialPhotoModelContainer context = this.CurrentDataSource;
            var comments = from d in context.Comments
                           where d.Photo.Id == photoId
                           select d;
            return comments;
        }

        [WebGet]
        public IQueryable<User> login(string username, string password)
        {
            SocialPhotoModelContainer context = this.CurrentDataSource;
            var user = from u in context.Users
                           where u.Name == username
                           && u.Password == password
                           select u;
            //User a;
            //a = user.FirstOrDefault();
            //if (a.Name != null)
            //{
            //    FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1,
            //a.Name,
            //DateTime.Now,
            //DateTime.Now.AddDays(30),
            //false,
            //"Administrator",
            //FormsAuthentication.FormsCookiePath);
            //    string encTicket = FormsAuthentication.Encrypt(ticket);
               
            ////    HttpContext.Current.User.IsInRole("Administrator");            
            //  // response.AddHeader("TEST HEADER","0987654321");
            //   //response.Headers.Add("TEST HEADER", "12222222");
               
            //}
            
            return user;
        }
        #endregion

        #region Security

        public int existUser (string username)
        {

            bool flag = true;
            SocialPhotoModelContainer context = this.CurrentDataSource;
            var user = from u in context.Users
                       where u.Name == username
                        select u;
            int count = user.Count();
            return count;

        }
 
        [ChangeInterceptor("Users")]
        public void ChangeUser(User user, UpdateOperations operations)
        {
            int count;
            count = existUser(user.Name);
            if (operations == UpdateOperations.Add && count >0)
                throw new DataServiceException(401, "Existed User");
        }
        [QueryInterceptor("Users")]
        public Expression<Func<User, bool>> OnQueryUsers()
        {
            string user = HttpContext.Current.Request.Headers["UserName"];
            string pass = HttpContext.Current.Request.Headers["Password"];

            bool flag;
            flag = checkUser(user, pass);

            if (flag == true)
                return (User u) => true;
            else
                return (User u) => false;
        }

        [QueryInterceptor("Photos")]
        public Expression<Func<Photo, bool>> OnQueryPhotos()
        {
            string user = HttpContext.Current.Request.Headers["UserName"];
            string pass = HttpContext.Current.Request.Headers["Password"];

            bool flag;
            flag = checkUser(user, pass);

            if (flag == true)
                return (Photo p) => true;
            else
                return (Photo p) => false;
        }

        [QueryInterceptor("Comments")]
        public Expression<Func<Comment, bool>> OnQueryComments()
        {
            string user = HttpContext.Current.Request.Headers["UserName"];
            string pass = HttpContext.Current.Request.Headers["Password"];

            bool flag;
            flag = checkUser(user, pass);

            if (flag == true)
                return (Comment c) => true;
            else
                return (Comment c) => false;
        }

        [QueryInterceptor("Categories")]
        public Expression<Func<Category, bool>> OnQueryCategory()
        {
            string user = HttpContext.Current.Request.Headers["UserName"];
            string pass = HttpContext.Current.Request.Headers["Password"];

            bool flag;
            flag = checkUser(user, pass);

            if(flag == true)
                return (Category cate) => true;
            else
                return (Category cate) => false;
        }
  
        public Boolean checkUser(string username, string password)
        {

            bool flag = false;
            SocialPhotoModelContainer context = this.CurrentDataSource;
            var user = from u in context.Users
                       where u.Name == username
                       && u.Password == password
                       select u;
            int count = user.Count();
            if (count > 0)
            {
                flag = true;
            }
            return flag;

        }
        //[QueryInterceptor("Categories")]
        //public Expression<Func<Category, bool>> OnQueryCategory()
        //{
        //    MembershipUser u = null;
        //    if (!string.IsNullOrEmpty(HttpContext.Current.User.Identity.Name))
        //    {
        //        u = Membership.GetUser(HttpContext.Current.User.Identity.Name);
        //    }
        //    else
        //    {
        //        string user = HttpContext.Current.Request.Headers["UserName"];
        //        string pass = HttpContext.Current.Request.Headers["Password"];
        //        if (Membership.ValidateUser(user, pass))
        //            u = Membership.GetUser(user);
        //    }
        //    if (u == null)
        //        return (Category cate) => false;
        //    Guid userId = new Guid(u.ProviderUserKey.ToString());
        //    return (Category cate) => true;
        //}

        #endregion
    }
}
